import React from 'react';
import { Layout, ConfigProvider, notification, message } from 'antd';
// import { getLocale } from 'umi-plugin-locale';

import zhCN from 'antd/es/locale/zh_CN';
import DocumentTitle from 'react-document-title';
import isEqual from 'lodash/isEqual';
import _ from 'lodash';
import memoizeOne from 'memoize-one';
import { connect } from 'umi';
import { ContainerQuery } from 'react-container-query';
import classNames from 'classnames';
import pathToRegexp from 'path-to-regexp';
import Media from 'react-media';
// import { history } from 'umi';
import { formatMessage } from 'umi';
// import cookie from 'js-cookie';
import { stringify } from 'qs';
import { transferMenuData } from '@/utils/enhanceUtils';
import Authorized from '@/utils/Authorized';
import SiderMenu from '@/components/SiderMenu';
import LeftSideMenu from '@/components/SiderMenu/LeftSideMenu';

import { renderTopMenu } from '@/utils/utils';

import { getFlatMenuKeys } from '@/components/SiderMenu/SiderMenuUtils';
// import getemployeemenu from '@/services/accessService';
// import BizIcon from '@/components/BizIcon';
import { getHeartBeat } from '@/services/user';
import PageTabs from '@/components/PageTabs';
import PageLoading from '@/components/PageLoading';
import { FeedbackFAB } from '@/pages/Feedback';
import InitUser from '@/pages/InitUser/index';

import plainLayoutConfig from '@/../config/plainLayout.config';
import blankLayoutPaths from '@/../config/blankLayout.config';

import WelcomeModal from '@/pages/EntryManage/components/WelcomeModal';
import IM from '@/pages/IM';

import withSubscribeMsg from '@/hooks/useSubscribeMsg/withSubscribeMsg';
import Msg from '@/hooks/useSubscribeMsg/Msg';
import styles from './BasicLayout.less';
import Context from './MenuContext';
import Header from './Header';
// import Footer from './Footer';
import logo from '../assets/logo.png';

const { Content } = Layout;

/**
 * 获取当前路由是否需要展示左侧菜单
 * @param pathname
 * @param routes
 */
function isNoSidebar(pathname, routes = []) {
    let noSidebar = false;

    routes.forEach(item => {
        if (item.path === pathname && item.noSidebar) {
            noSidebar = true;
        } else if (item.routes) {
            noSidebar = isNoSidebar(pathname, item.routes);
        }
    });

    return noSidebar;
}

const query = {
    // 'screen-xs': {
    //     maxWidth: 575
    // },
    // 'screen-sm': {
    //     minWidth: 576,
    //     maxWidth: 767
    // },
    // 'screen-md': {
    //     minWidth: 768,
    //     maxWidth: 991
    // },
    // 'screen-lg': {
    //     minWidth: 992,
    //     maxWidth: 1199
    // },
    // 'screen-xl': {
    //     minWidth: 1200,
    //     maxWidth: 1599
    // },
    // 'screen-xxl': {
    //     minWidth: 1600
    // }
};

const isProd = process.env.ENV === 'production';
// console.log(getLocale(), 'xxx');
class BasicLayout extends React.PureComponent {
    constructor(props) {
        super(props);
        this.getPageTitle = memoizeOne(this.getPageTitle);
        this.matchParamsPath = memoizeOne(this.matchParamsPath, isEqual);
        const currentUser = localStorage.getItem('user') ? JSON.parse(localStorage.getItem('user')) : {};
        this.state = {
            companyId: currentUser.companyId,
            isInit: false,
            userCode: currentUser.employeeCode
        };
        this.timer = null;
        this.taskTimer = null;
    }

    componentDidMount() {
        const {
            dispatch,
            route: { routes, authority },
            location: { pathname }
        } = this.props;

        dispatch({
            type: 'global/getMsgCount'
        });

        // 获取侧边栏任务数量
        dispatch({
            type: 'global/getSelfTaskCount'
        });

        dispatch({
            type: 'user/fetchCurrent',
            callback: data => {
                //  接口优化，获取用户个人头像
                dispatch({
                    type: 'user/fetchPersonalPortrait'
                });
                // 用户首次登陆的逻辑都放进来这里面
                if (data.isInit === undefined) {
                    dispatch({
                        type: 'setting/getSetting'
                    });
                    dispatch({
                        type: 'menu/getMenuData',
                        payload: { routes, authority, pathname }
                    });

                    // 清空提示数量
                    dispatch({
                        type: 'global/clearPropmtCounts'
                    });

                    // 获取绑定邮箱列表，遵照旧代码风格!!so，这个嵌套真恶心
                    dispatch({
                        type: 'user/fetchMailBindInfo',
                        payload: {
                            userCode: this.state.userCode
                        },
                        callback: async response => {
                            if (_.size(response.data) > 0) {
                                // 5分钟自动同步一次邮箱
                                this.mailPullTimer = setInterval(() => {
                                    // 先同步服务器邮件
                                    dispatch({
                                        type: 'global/fetchPullList',
                                        callback: res => {
                                            if (res.code === 10000 && res.data.fetchCount > 0) {
                                                // 拉取未读信息
                                                dispatch({
                                                    type: 'global/fetchMailPrompt',
                                                    payload: { userCode: this.state.userCode },
                                                    callback: result => {
                                                        if (result.code === 10000) {
                                                            const { totalUnReadCount = 0 } = result.data;
                                                            if (totalUnReadCount > 0) {
                                                                notification.destroy();
                                                                notification.success({
                                                                    message: (
                                                                        <div>
                                                                            收到新邮件，共有
                                                                            <b style={{ color: '#f00' }}>
                                                                                {totalUnReadCount}
                                                                            </b>
                                                                            条未读
                                                                        </div>
                                                                    ),
                                                                    placement: 'bottomRight',
                                                                    duration: 5
                                                                });
                                                            }
                                                        }
                                                    }
                                                });
                                            }
                                        }
                                    });
                                }, 3 * 60 * 1000);
                            }

                            // 拉取邮箱未读信息
                            await dispatch({
                                type: 'global/fetchMailPrompt',
                                payload: {
                                    userCode: this.state.userCode
                                },
                                callback: res => {
                                    if (res.code !== 10000) {
                                        // message.error(res.msg);
                                    }
                                }
                            });
                            // 获取待办任务数量
                            // DELETE
                            // await dispatch({
                            //     type: 'global/fetchTaskCount',
                            //     callback: res => {
                            //         if (res.code !== 10000) {
                            //             // message.error(res.msg);
                            //         }
                            //     }
                            // });

                            await dispatch({
                                type: 'global/fetchNewFunctionCount',
                                callback: res => {
                                    if (res.code !== 10000) {
                                        // message.error(res.msg)
                                    }
                                }
                            });

                            this.updateMenuPrompt();
                        }
                    });

                    dispatch({
                        type: 'user/fetchMailBindTemplates'
                    });
                }
                this.setState({
                    companyId: data.companyId,
                    isInit: data.isInit !== undefined
                });
            }
        });

        // this.heartBeat();
        if (isProd) this.webpref();
    }

    componentDidUpdate(prevProps) {
        // 邮箱绑定列表有变化，请求邮箱未读数量
        if (this.props.user.mailBindList !== prevProps.user.mailBindList) {
            this.props.dispatch({
                type: 'global/fetchMailPrompt',
                payload: {
                    userCode: this.state.userCode
                },
                callback: res => {
                    if (res.code !== 10000) {
                        message.error(res.msg);
                    }
                }
            });
        }

        if (this.props.subContent !== prevProps.subContent) {
            const { type } = this.props.subContent;
            switch (type) {
                case 'todo': {
                    this.props.dispatch({
                        type: 'global/getSelfTaskCount'
                    });
                    break;
                }
                case 'notice': {
                    this.props.dispatch({
                        type: 'global/getMsgCount'
                    });
                    break;
                }
                default:
                    break;
            }
        }

        if (
            this.props.user.currentUser !== prevProps.user.currentUser ||
            this.props.noticeCount !== prevProps.noticeCount ||
            this.props.mailPromptCount !== prevProps.mailPromptCount ||
            this.props.user.mailBindList !== prevProps.user.mailBindList ||
            this.props.selfTaskCount !== prevProps.selfTaskCount
        ) {
            this.updateMenuPrompt();
        }
    }

    // TODO 先注释掉，忘了加这个有啥意义了
    // componentDidUpdate(preProps) {
    //     // After changing to phone mode,
    //     // if collapsed is true, you need to click twice to display
    //     const { collapsed, isMobile, location, dispatch } = this.props;
    //     if (isMobile && !preProps.isMobile && !collapsed) {
    //         this.handleMenuCollapse(false);
    //     }
    //
    //     if (preProps.location.pathname !== location.pathname) {
    //         const {
    //             route: { routes, authority },
    //             location: { pathname }
    //         } = this.props;
    //         dispatch({
    //             type: 'menu/getMenuData',
    //             payload: {
    //                 // result: preProps.result,
    //                 routes,
    //                 pathname,
    //                 authority
    //             }
    //         });
    //     }
    // }
    // componentWillReceiveProps(nextProps, nextContext) {
    //     const { location } = this.props;
    //     if(nextProps.location.pathname !== location.pathname){
    //         this.webpref();
    //     }
    // }

    componentWillUnmount() {
        this.setState({
            isInit: false,
            userCode: null
        });
        if (this.mailPullTimer) {
            clearInterval(this.mailPullTimer);
        }
        if (this.taskTimer) {
            clearInterval(this.taskTimer);
        }
    }

    getContext() {
        const { location, breadcrumbNameMap } = this.props;
        return {
            location,
            breadcrumbNameMap
        };
    }

    /**
     * 调用服务端心跳接口，每3秒一次，响应时间超过1秒记为慢请求，连续3次弹窗提示。
     */
    heartBeat = () => {
        const timeOut = 1000;
        let num = 0; // 超过1秒的次数
        this.timer = setInterval(async () => {
            if (num >= 3) {
                num = 0;
                notification.destroy();
                notification.warning({
                    message: '请注意',
                    description: '当前网络访问速度偏慢',
                    placement: 'bottomRight'
                });
            }
            const startTime = +new Date();
            await getHeartBeat();
            const endTime = +new Date();
            if (endTime - startTime >= timeOut) {
                num += 1;
            } else {
                num = 0;
            }
        }, 3000);
    };

    // 上传监控参数
    webpref = () => {
        if (typeof fetch !== 'undefined' && window.performance) {
            fetch(`/api/oa/v1/webpref?${stringify(window.performance.timing.toJSON())}`, {
                method: 'GET',
                cache: 'no-cache'
            });
        }
    };

    // 菜单未读数量初始化
    updateMenuPrompt = () => {
        const { dispatch, noticeCount, mailPromptCount, taskCount, newFunctionCount, selfTaskCount } = this.props;
        const { totalUnReadCount = 0 } = mailPromptCount;
        const {
            toExecuteTaskNum = 0,
            toAuditTaskNum = 0,
            toAcceptTaskNum = 0,
            toScoreTaskNum = 0,
            toEstimateTaskNum = 0
        } = taskCount;

        dispatch({
            type: 'menu/saveMenu',
            payload: {
                count: noticeCount,
                path: '/personal/message/system'
            }
        });
        dispatch({
            type: 'menu/saveMenu',
            payload: {
                count: noticeCount + totalUnReadCount,
                path: '/personal/message'
            }
        });
        dispatch({
            type: 'menu/saveMenu',
            payload: {
                count: totalUnReadCount,
                path: '/personal/message/mails'
            }
        });
        dispatch({
            type: 'menu/saveMenu',
            payload: {
                count: toExecuteTaskNum + toAuditTaskNum + toAcceptTaskNum + toScoreTaskNum + toEstimateTaskNum,
                path: '/work/task'
            }
        });
        dispatch({
            type: 'menu/saveMenu',
            payload: {
                count: toExecuteTaskNum + toAuditTaskNum + toAcceptTaskNum + toScoreTaskNum + toEstimateTaskNum,
                path: '/work/task/mytask'
            }
        });
        dispatch({
            type: 'menu/saveMenu',
            payload: {
                count: toExecuteTaskNum,
                path: '/work/task/mytask/execute'
            }
        });
        dispatch({
            type: 'menu/saveMenu',
            payload: {
                count: toAuditTaskNum,
                path: '/work/task/mytask/audit'
            }
        });
        dispatch({
            type: 'menu/saveMenu',
            payload: {
                count: toAcceptTaskNum,
                path: '/work/task/mytask/acceptance'
            }
        });
        dispatch({
            type: 'menu/saveMenu',
            payload: {
                count: toScoreTaskNum,
                path: '/work/task/mytask/score'
            }
        });
        dispatch({
            type: 'menu/saveMenu',
            payload: {
                count: toEstimateTaskNum,
                path: '/work/task/mytask/assessment'
            }
        });
        dispatch({
            type: 'menu/saveMenu',
            payload: {
                count: newFunctionCount,
                path: '/setting/privilege/newFunctionList'
            }
        });
        dispatch({
            type: 'menu/saveMenu',
            payload: {
                count: selfTaskCount,
                path: '/personal/todo'
            }
        });
    };

    matchParamsPath = (pathname, breadcrumbNameMap) => {
        const pathKey = Object.keys(breadcrumbNameMap).find(key => pathToRegexp(key).test(pathname));
        return breadcrumbNameMap[pathKey];
    };

    getRouterAuthority = (pathname, routeData) => {
        let routeAuthority = ['noAuthority'];
        const getAuthority = (key, routes) => {
            routes.map(route => {
                if (route.path === key) {
                    routeAuthority = route.authority;
                } else if (route.routes) {
                    routeAuthority = getAuthority(key, route.routes);
                }
                return route;
            });
            return routeAuthority;
        };
        return getAuthority(pathname, routeData);
    };

    getPageTitle = (pathname, breadcrumbNameMap) => {
        const currRouterData = this.matchParamsPath(pathname, breadcrumbNameMap);

        if (!currRouterData) {
            return '微微科技集团管理系统';
        }
        const pageName = formatMessage({
            id: currRouterData.locale || currRouterData.name,
            defaultMessage: currRouterData.name
        });

        return `${pageName} - 微微科技集团管理系统`;
    };

    getLayoutStyle = () => {
        const { fixSiderbar, isMobile, collapsed, layout } = this.props;
        if (fixSiderbar && layout !== 'topmenu' && !isMobile) {
            return {
                paddingLeft: collapsed ? '80px' : '256px'
            };
        }
        return null;
    };

    handleMenuCollapse = collapsed => {
        const { dispatch } = this.props;
        dispatch({
            type: 'global/changeLayoutCollapsed',
            payload: collapsed
        });
    };

    chnageCompanyId = companyId => {
        // const {
        //     route: { routes },
        //     dispatch
        // } = this.props;
        this.setState(
            {
                companyId
            },
            () => {
                // const {
                //     route: { routes, authority },
                //     location: { pathname }
                // } = this.props;
                // dispatch({
                //     type: 'menu/getMenuData',
                //     payload: {
                //         // result: preProps.result,
                //         routes,
                //         pathname,
                //         authority,
                //         goHome: true
                //     }
                // });
                // 切换公司后刷新页面
                window.location.href = '/';
            }
        );
    };

    render() {
        const {
            navTheme,
            layout: PropsLayout,
            children,
            location: { pathname },
            isMobile,
            menuData,
            breadcrumbNameMap,
            route: { routes },
            fixedHeader,
            pageTabs = true,
            // firstMenu,
            menuLoading,
            dispatch
        } = this.props;
        const { companyId, isInit } = this.state;
        const isTop = PropsLayout === 'topmenu';
        const routerConfig = this.getRouterAuthority(pathname, routes);
        const contentStyle = !fixedHeader ? { paddingTop: 0 } : {};
        const flatMenuKeys = getFlatMenuKeys(menuData);
        const renderMenuData = transferMenuData(menuLoading, menuData);
        const plainLayout = plainLayoutConfig.find(item => item.path === pathname);
        const isBlankLayout = blankLayoutPaths.some(item => item.path === pathname);
        const renderContent = () => {
            if (pageTabs) {
                if (renderMenuData) {
                    return <PageTabs {...this.props} />;
                }
                return <PageLoading />;
            }
            return children;
        };

        const renderLayout = () => {
            if (isInit) return <InitUser />;
            if (plainLayout) return children;
            return (
                <Layout
                    style={{ flex: 1 }}
                    className={classNames(styles.menu, {
                        'no-sidebar': isNoSidebar(pathname, routes)
                    })}
                >
                    <LeftSideMenu
                        mode="inline"
                        style={{
                            height: '100%',
                            borderRight: 0
                        }}
                        {...this.props}
                        flatMenuKeys={flatMenuKeys}
                        // menuData={firstMenu ? firstMenu.children : []}
                        menuData={menuData}
                        breadcrumbNameMap={breadcrumbNameMap}
                    />
                    <Layout id="__layout__" style={{ display: 'block', position: 'relative' }}>
                        <Content className={styles.content} style={contentStyle}>
                            <Authorized
                                authority={routerConfig}
                                // noMatch={<p>Exception403</p>}
                                noMatch={<p />}
                            >
                                <ConfigProvider
                                    locale={zhCN}
                                    getPopupContainer={() => document.getElementById('__layout__')}
                                >
                                    {renderContent()}
                                    {/* <Footer /> */}
                                </ConfigProvider>
                            </Authorized>
                        </Content>
                    </Layout>
                </Layout>
            );
        };

        const layout = () => {
            if (isBlankLayout) {
                return children;
            }
            return (
                <Layout style={{ height: '100%' }} key={companyId}>
                    {isTop && !isMobile ? null : (
                        <SiderMenu
                            logo={logo}
                            theme={navTheme}
                            onCollapse={this.handleMenuCollapse}
                            menuData={renderTopMenu(menuData)}
                            isMobile={isMobile}
                            {...this.props}
                        />
                    )}
                    <Layout
                        style={{
                            ...this.getLayoutStyle(),
                            height: '100%',
                            display: 'flex'
                        }}
                    >
                        <Header
                            menuData={menuData}
                            plainLayout={plainLayout}
                            handleMenuCollapse={this.handleMenuCollapse}
                            logo={logo}
                            isMobile={isMobile}
                            onSelect={({ key }) => {
                                dispatch({
                                    type: 'menu/save',
                                    payload: {
                                        firstMenu: menuData.find(i => i.path === key)
                                    }
                                });
                            }}
                            onGoHome={() => {
                                dispatch({
                                    type: 'menu/save',
                                    payload: {
                                        firstMenu: menuData[0] || {}
                                    }
                                });
                                sessionStorage.removeItem('orgListTableExpandedRowKeys'); // 清除机构管理的列表展开的状态
                            }}
                            companyId={companyId}
                            chnageCompanyId={this.chnageCompanyId}
                            {...this.props}
                        />
                        {renderLayout()}
                    </Layout>
                </Layout>
            );
        };

        return (
            <React.Fragment>
                <DocumentTitle title={this.getPageTitle(pathname, breadcrumbNameMap)}>
                    <ContainerQuery query={query}>
                        {params => (
                            <Context.Provider value={this.getContext()}>
                                <div style={isBlankLayout ? {} : { height: '100%' }} className={classNames(params)}>
                                    {layout()}
                                </div>
                                {!isBlankLayout && <FeedbackFAB />}
                            </Context.Provider>
                        )}
                    </ContainerQuery>
                </DocumentTitle>
                <WelcomeModal />
                <IM />
            </React.Fragment>
        );
    }
}

export default withSubscribeMsg(
    connect(({ global, setting, menu, loading, user }) => ({
        collapsed: global.collapsed,
        noticeCount: global.noticeCount,
        mailPromptCount: global.mailPromptCount,
        taskCount: global.taskCount,
        newFunctionCount: global.newFunctionCount,
        layout: setting.layout,
        menuData: menu.menuData,
        result: menu.result,
        firstMenu: menu.firstMenu,
        breadcrumbNameMap: menu.breadcrumbNameMap,
        avatarFile: user.avatarFile,
        selfTaskCount: global?.userTask?.unFinishCount || 0,
        user,
        ...setting,

        originalMenuData: menu.originalMenuData,
        menuLoading: loading.effects['menu/getMenuData']
    }))(props => <Media query="(max-width: 1px)">{isMobile => <BasicLayout {...props} isMobile={isMobile} />}</Media>),
    {
        subType: [Msg.todo, Msg.notice]
    }
);
